package com.insmess.meeting.sdk;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.insmess.meeting.sdk.dto.*;
import org.apache.commons.beanutils.BeanMap;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

public class ImMeetingSdk {

    //后端的url
    private String baseUrl;
    private CloseableHttpClient httpClient;

    public ImMeetingSdk(String baseUrl) {
        this.baseUrl = baseUrl;
        httpClient = HttpClients.createDefault();
    }

    //==========================================================会议房间开始====================================================
    /**
     * 添加会议房间
     *
     * @param imRoom
     */
    public ImResultDto<ImRoom> saveRoom(ImRoom imRoom) throws IOException {
        if (imRoom == null) {
            throw new RuntimeException("不接受空值");
        }
        return saveOrUpdateRoom(imRoom, baseUrl + "/room/save");
    }

    /**
     * 修改会议房间
     *
     * @param imRoom
     */
    public ImResultDto<ImRoom> updateRoom(ImRoom imRoom) throws IOException {
        if (imRoom == null) {
            throw new RuntimeException("不接受空值");
        }
        return saveOrUpdateRoom(imRoom, baseUrl + "/room/update");
    }

    /**
     * 根据id删除会议房间
     *
     * @param id
     */
    public ImResultDto deleteRoomById(String id) throws IOException {
        HttpPost http = new HttpPost(baseUrl + "/room/deleteById");
        return deleteById(id, http);
    }

    public ImResultDto<ImRoom> getRoomById(String id) throws IOException {
        String url = baseUrl + "/room/findById" + "?id=" + id;
        HttpGet http = new HttpGet(url);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<ImRoom> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<ImRoom>>() {});
            //转换类型
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }


    public ImResultDto<List<ImRoom>> listRoomByIds(List<String> ids) throws IOException {
        String params = "";
        for (int i = 0; i < ids.size(); i++) {
            String id = ids.get(i);
            params += ("ids=" + id);
            if (i != ids.size() - 1) {
                params += "&";
            }
        }
        String url = baseUrl + "/room/findListByIds" + "?" + params;
        HttpGet http = new HttpGet(url);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<List<ImRoom>> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<List<ImRoom>>>() {});
            //转换类型
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }

    /**
     * 条件查询所有
     *
     * @param imRoom
     * @return
     */
    public ImResultDto<List<ImRoom>> listRoom(ImRoom imRoom) throws IOException, URISyntaxException {
        if (imRoom == null) {
            imRoom = new ImRoom();
        }
        String url = beanToParamsStr(baseUrl + "/room/findList", imRoom);
        HttpGet http = new HttpGet(url);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<List<ImRoom>> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<List<ImRoom>>>() {});
            //转换类型
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }

    /**
     * 分页查询所有
     *
     * @param imRoom
     * @return
     */
    public ImResultDto<ImPage<ImRoom>> pageRoom(ImRoom imRoom, Integer pageNum, Integer pageSize) throws IOException, URISyntaxException {
        if (imRoom == null) {
            imRoom = new ImRoom();
        }
        String url = beanToParamsStr(baseUrl + "/room/findPage", imRoom, pageNum, pageSize);
        HttpGet http = new HttpGet(url);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<ImPage<ImRoom>> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<ImPage<ImRoom>>>() {});
            //转换类型
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }

    //==========================================================会议房间结束====================================================



    //==========================================================会议聊天开始====================================================
    /**
     * 添加会议房间
     *
     * @param imRoomChat
     */
    public ImResultDto saveRoomChat(ImRoomChat imRoomChat) throws IOException {
        if (imRoomChat == null) {
            throw new RuntimeException("不接受空值");
        }
        return saveOrUpdate(imRoomChat, baseUrl + "/roomChat/save");
    }

    /**
     * 修改会议房间
     *
     * @param imRoomChat
     */
    public ImResultDto updateRoomChat(ImRoomChat imRoomChat) throws IOException {
        if (imRoomChat == null) {
            throw new RuntimeException("不接受空值");
        }
        return saveOrUpdate(imRoomChat, baseUrl + "/roomChat/update");
    }

    /**
     * 根据id删除会议房间
     *
     * @param id
     */
    public ImResultDto deleteRoomChatById(String id) throws IOException {
        HttpPost http = new HttpPost(baseUrl + "/roomChat/deleteById");
        return deleteById(id, http);
    }

    /**
     * 条件查询所有
     *
     * @param imRoomChat
     * @return
     */
    public ImResultDto<List<ImRoomChat>> listRoomChat(ImRoomChat imRoomChat) throws IOException, URISyntaxException {
        if (imRoomChat == null) {
            imRoomChat = new ImRoomChat();
        }
        String url = beanToParamsStr(baseUrl + "/roomChat/findList", imRoomChat);
        HttpGet http = new HttpGet(url);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<List<ImRoomChat>> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<List<ImRoomChat>>>() {});
            //转换类型
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }

    /**
     * 分页查询所有
     *
     * @param imRoomChat
     * @return
     */
    public ImResultDto<ImPage<ImRoomChat>> pageRoomChat(ImRoomChat imRoomChat, Integer pageNum, Integer pageSize) throws IOException, URISyntaxException {
        if (imRoomChat == null) {
            imRoomChat = new ImRoomChat();
        }
        String url = beanToParamsStr(baseUrl + "/roomChat/findPage", imRoomChat, pageNum, pageSize);
        HttpGet http = new HttpGet(url);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<ImPage<ImRoomChat>> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<ImPage<ImRoomChat>>>() {});
            //转换类型
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }

    //==========================================================会议聊天结束====================================================


    //==========================================================会议文件开始====================================================
    /**
     * 添加会议房间
     *
     * @param imRoomFile
     */
    public ImResultDto saveRoomFile(ImRoomFile imRoomFile) throws IOException {
        if (imRoomFile == null) {
            throw new RuntimeException("不接受空值");
        }
        return saveOrUpdate(imRoomFile, baseUrl + "/roomFile/save");
    }

    /**
     * 修改会议房间
     *
     * @param imRoomFile
     */
    public ImResultDto updateRoomFile(ImRoomFile imRoomFile) throws IOException {
        if (imRoomFile == null) {
            throw new RuntimeException("不接受空值");
        }
        return saveOrUpdate(imRoomFile, baseUrl + "/roomFile/update");
    }

    /**
     * 根据id删除会议房间
     *
     * @param id
     */
    public ImResultDto deleteRoomFile(String id) throws IOException {
        HttpPost http = new HttpPost(baseUrl + "/roomFile/deleteById");
        return deleteById(id, http);
    }

    /**
     * 条件查询所有
     *
     * @param imRoomFile
     * @return
     */
    public ImResultDto<List<ImRoomFile>> listRoomFile(ImRoomFile imRoomFile) throws IOException, URISyntaxException {
        if (imRoomFile == null) {
            imRoomFile = new ImRoomFile();
        }
        String url = beanToParamsStr(baseUrl + "/roomFile/findList", imRoomFile);
        HttpGet http = new HttpGet(url);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<List<ImRoomFile>> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<List<ImRoomFile>>>() {});
            //转换类型
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }

    /**
     * 分页查询所有
     *
     * @param imRoomFile
     * @return
     */
    public ImResultDto<ImPage<ImRoomFile>> pageRoomFile(ImRoomFile imRoomFile, Integer pageNum, Integer pageSize) throws IOException, URISyntaxException {
        if (imRoomFile == null) {
            imRoomFile = new ImRoomFile();
        }
        String url = beanToParamsStr(baseUrl + "/roomFile/findPage", imRoomFile, pageNum, pageSize);
        HttpGet http = new HttpGet(url);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<ImPage<ImRoomFile>> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<ImPage<ImRoomFile>>>() {});
            //转换类型
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }

    //==========================================================会议文件结束====================================================

    //==========================================================会议录屏开始========================================================

    public ImResultDto<List<ImRoomRecord>> listRoomRecordByMeetingId(String meetingId) throws IOException {
        String url = baseUrl + "/roomRecord/getByMeetingId" + "?meetingId=" + meetingId;
        HttpGet http = new HttpGet(url);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<List<ImRoomRecord>> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<List<ImRoomRecord>>>() {});
            //转换类型
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }


    //==========================================================会议录屏结束========================================================


    private ImResultDto<ImRoom> saveOrUpdateRoom(ImRoom room, String apiUrl) throws IOException {
        HttpPost http = new HttpPost(apiUrl);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        //序列号json
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = objectMapper.writeValueAsString(room);
        http.setEntity(new StringEntity(jsonStr, "UTF-8"));
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<ImRoom> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<ImRoom>>() {});
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }

    private <T> ImResultDto<T> saveOrUpdate(T t, String apiUrl) throws IOException {
        HttpPost http = new HttpPost(apiUrl);
        http.setHeader("Content-Type", "application/json;charset=utf-8");
        //序列号json
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = objectMapper.writeValueAsString(t);
        http.setEntity(new StringEntity(jsonStr, "UTF-8"));
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            String resultJson = EntityUtils.toString(entity);
            ImResultDto<T> imResultDto = objectMapper.readValue(resultJson, new TypeReference<ImResultDto<T>>() {});
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }

    private <T> ImResultDto<T> deleteById(String id, HttpPost http) throws IOException {
        http.setHeader("Content-Type", "application/text;charset=utf-8");
        http.setEntity(new StringEntity("id=" + id));
        CloseableHttpResponse resp = httpClient.execute(http);
        HttpEntity entity = resp.getEntity();
        if (entity != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            String resultJson = EntityUtils.toString(entity);
            ImResultDto imResultDto = objectMapper.readValue(resultJson, ImResultDto.class);
            return imResultDto;
        }
        throw new RuntimeException("操作失败");
    }

    private static <T> String beanToParamsStr(String apiUrl, T t) throws URISyntaxException, UnsupportedEncodingException {
        //将对象转集合
        return beanToParamsStr(apiUrl, t, null, null);
    }

    private static <T> String beanToParamsStr(String apiUrl, T t, Integer pageNum, Integer pageSize) throws URISyntaxException, UnsupportedEncodingException {
        //将对象转集合
        BeanMap map = new BeanMap(t);

        // 合并原始API路径与参数
        StringBuilder queryParams = new StringBuilder();
        for (Map.Entry<Object, Object> entry : map.entrySet()) {
            if (entry.getValue() != null && !entry.getKey().equals("class")) {
                queryParams.append(entry.getKey()).append("=").append(URLEncoder.encode(String.valueOf(entry.getValue()), "utf-8")).append("&");
            }
        }
        if (pageNum != null) {
            queryParams.append("pageNum").append("=").append(pageNum).append("&");
        }
        if (pageSize != null) {
            queryParams.append("pageSize").append("=").append(pageSize).append("&");
        }
        // 移除最后一个 "&" 如果存在
        if (queryParams.length() > 1) queryParams.setLength(queryParams.length() - 1);

        return apiUrl + "?" + queryParams.toString();
    }

    private static <T> String beanToParamsStr(T t, Integer pageNum, Integer pageSize) throws UnsupportedEncodingException {
        //将对象转集合
        BeanMap map = new BeanMap(t);

        // 合并原始API路径与参数
        StringBuilder queryParams = new StringBuilder();
        for (Map.Entry<Object, Object> entry : map.entrySet()) {
            if (entry.getValue() != null && !entry.getKey().equals("class")) {
                queryParams.append(entry.getKey()).append("=").append(URLEncoder.encode(String.valueOf(entry.getValue()), "utf-8")).append("&");
            }
        }
        if (pageNum != null) {
            queryParams.append("pageNum").append("=").append(pageNum).append("&");
        }
        if (pageSize != null) {
            queryParams.append("pageSize").append("=").append(pageSize).append("&");
        }
        // 移除最后一个 "&" 如果存在
        if (queryParams.length() > 1) queryParams.setLength(queryParams.length() - 1);

        return "?" + queryParams.toString();
    }

    public static void main(String[] args) throws UnsupportedEncodingException, URISyntaxException {
        ImRoom imRoom = new ImRoom();
        imRoom.setName("xxx");
        imRoom.setId("aa");
        String result = beanToParamsStr("http://xxx.com", imRoom);

        System.out.println(result);
    }

}
